package com.gua.user.service.impl;

import com.gua.common.enums.AlwaysShowEnum;
import com.gua.common.enums.HideEnum;
import com.gua.common.enums.NoCacheEnum;
import com.gua.user.response.*;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gua.user.entity.ManagementMenu;
import com.gua.user.mapper.ManagementMenuMapper;
import com.gua.user.service.IManagementMenuService;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 
 * @author huangjj
 *
 */
@Service
public class ManagementMenuServiceImpl extends ServiceImpl<ManagementMenuMapper, ManagementMenu> implements IManagementMenuService {

    @Override
    public List<ManagementMenuRespVO> getMenusByUserId() {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        List<ManagementMenuDTO> allMenus = baseMapper.getMenusByUserId(loginUser.getUser().getId());
        if(allMenus == null){
            allMenus = new ArrayList<>();
        }

        List<ManagementMenuRespVO> resultMenus = new ArrayList<>();

        allMenus.forEach(menu -> {
            ManagementMenuRespVO managementMenuRespVO = new ManagementMenuRespVO();
            managementMenuRespVO.setId(menu.getId());
            managementMenuRespVO.setName(menu.getName());
            managementMenuRespVO.setRedirect(menu.getRedirect());
            managementMenuRespVO.setPath(menu.getPath());
            managementMenuRespVO.setComponent(menu.getComponent());
            //菜单状态（0隐藏；1显示）
            if(HideEnum.HIDE.getCode() == menu.getHidden()) {
                managementMenuRespVO.setHidden(true);
            }else{
                managementMenuRespVO.setHidden(false);
            }
            //是否一直显示（0一直展示 1可关闭）
            managementMenuRespVO.setAlwaysShow(AlwaysShowEnum.ALWAYS_SHOW.getCode()== menu.getAlwaysShow()? true : false);
            managementMenuRespVO.setSort(menu.getSort() == null? 0 : menu.getSort());
            managementMenuRespVO.setParentId(menu.getParentId());
            managementMenuRespVO.setChildren(new ArrayList<>());

            MenuMetaDTO menuMetaDTO = new MenuMetaDTO();
            menuMetaDTO.setTitle(menu.getTitle());
            menuMetaDTO.setIcon(menu.getIcon());
            //是否缓存，0缓存，1不缓存
            menuMetaDTO.setNoCache(NoCacheEnum.NO_CACHE.getCode() == menu.getNoCache() ? true : false);
            menuMetaDTO.setActiveMenu(menu.getActiveMenu());
            managementMenuRespVO.setMeta(menuMetaDTO);

            resultMenus.add(managementMenuRespVO);
        });

        // https://blog.csdn.net/xie1016/article/details/123750710
        //2.组装成父子树形结构
        //2.1)、找到所有的一级分类
        List<ManagementMenuRespVO> level1Menus = resultMenus.stream().filter((managementMenuRespVO) -> {
            return managementMenuRespVO.getParentId() == 0L;
        }).map((menu) -> {
            menu.setChildren(getChildren(menu, resultMenus));
            return menu;
        }).sorted((menu1, menu2) -> {
            return (menu1.getSort() - menu2.getSort());
        }).collect(Collectors.toList());
        return level1Menus;
    }

    /**
     * 递归查找所有菜单的子菜单
     * @param root
     * @param allManagementMenuRespVO
     * @return
     */
    private List<ManagementMenuRespVO> getChildren(ManagementMenuRespVO root, List<ManagementMenuRespVO> allManagementMenuRespVO) {
        List<ManagementMenuRespVO> children = allManagementMenuRespVO.stream()
            .filter((managementMenuRespVO) -> {
                return managementMenuRespVO.getParentId() == root.getId();
            }).map((entity) -> {
                //1.找到子菜单
                    entity.setChildren(getChildren(entity, allManagementMenuRespVO));
                return entity;
            }).sorted((menu1, menu2) -> {
                //2.菜单的排序
                return (menu1.getSort() - menu2.getSort());
            }).collect(Collectors.toList());
        return children;
    }
}
